/*
 * @Author: 江舟 jijiangzhou@recycloud.cn
 * @Date: 2024-04-22 13:52:24
 * @LastEditors: 江舟 jijiangzhou@recycloud.cn
 * @LastEditTime: 2024-07-03 15:17:41
 * @FilePath: \web\src\components\SearchMenuTree\Index.tsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import { Empty, Spin, Tree, Input, Tag, TreeDataNode } from 'antd';
import React, { useImperativeHandle } from 'react';
import { useEffect, useState, useMemo } from 'react';

const { Search } = Input;

interface MenuTreeProps {
	parentId?: string | null;
	appId?: string | null;
	queryCondition?: string | null;
	onSelect: (_selectedKeys: any, e: any) => void;
	onUpdateTreeData: (data: any) => void;
	api: () => Promise<any>;
	fieldNamesTitle?: string;
	fieldNamesKey?: string;
	ref?: any;
	needAppId?: boolean;
	treeKeyInName?: string;
	search?: boolean;
}

const MenuTree: React.FC<MenuTreeProps> = React.forwardRef(
	({ fieldNamesTitle = 'label', fieldNamesKey = 'id', onSelect = () => {}, onUpdateTreeData = () => {}, api, parentId }, ref) => {
		// org tree
		const [menuTreeData, setMenuTreeData] = useState<{}[]>([]);
		const [menuTreeLoading, setMenuTreeLoading] = useState(false);
		const [refresh, setRefresh] = useState<number>();
		const [searchValue, setSearchValue] = useState('');

		const treeData = useMemo(() => {
			if (!searchValue) {
				return menuTreeData;
			}
			const loop = data =>
				data
					.map(item => {
						const index = item.label.indexOf(searchValue);
						const beforeStr = item.label.substr(0, index);
						const afterStr = item.label.substr(index + searchValue.length);
						const title =
							index > -1 ? (
								<span>
									{beforeStr}
									<span className="site-tree-search-value">{searchValue}</span>
									{afterStr}
								</span>
							) : (
								<span>{item.title}</span>
							);
						if (item.children && item.children.length > 0) {
							const children = loop(item.children);
							return {
								...item,
								title: index > -1 || children.length ? title : null,
								children: children.length ? children : undefined,
							};
						}
						return index > -1
							? {
									...item,
									title,
							  }
							: {
									...item,
									title: null,
							  };
					})
					.filter(item => !!item.title);

			return loop(menuTreeData);
		}, [searchValue, menuTreeData]);

		const getMenuTreeData = async () => {
			setMenuTreeLoading(true);
			setMenuTreeData([]);
			try {
				const res: any = await api?.();
				setMenuTreeData([res?.menuTree] || []);
				onUpdateTreeData([res?.menuTree] || []);
			} finally {
				setMenuTreeLoading(false);
			}
		};

		const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
			const { value } = e.target;
			setSearchValue(value);
		};

		useEffect(() => {
			getMenuTreeData();
		}, [refresh]);

		useImperativeHandle(
			ref,
			() => {
				return {
					refresh: () => setRefresh(new Date().getTime()),
				};
			},
			[],
		);

		return (
			<Spin spinning={menuTreeLoading} className="w-250px min-h-500px">
				{menuTreeData?.length ? (
					<>
						<Search value={searchValue} className="w-276px mb-24px" placeholder="请输入菜单名" onChange={onChange} />
						<div className="overflow-auto" style={{ height: 'calc(100vh - 348px)' }}>
							<Tree
								titleRender={nodeData => {
									return (
										<div>
											{nodeData.module === 1 || nodeData.module === 2 ? (
												<Tag color={nodeData.module === 1 ? 'blue' : 'success'}>
													{nodeData.module === 1 ? 'PC' : '移动'}
												</Tag>
											) : null}

											{nodeData.label}
										</div>
									);
								}}
								selectedKeys={[parentId]}
								defaultExpandAll={true}
								showLine={true}
								showIcon={false}
								onSelect={onSelect}
								treeData={treeData}
								fieldNames={{
									title: fieldNamesTitle,
									key: fieldNamesKey,
								}}
							/>
						</div>
					</>
				) : (
					<Empty className="ml-30px" />
				)}
			</Spin>
		);
	},
);

export default MenuTree;
